---
title: Compilation Hooks
group: Plugins
sort: 10
contributors:
  - slavafomin
  - byzyk
  - madhavarshney
  - misterdev
  - wizardofhogwarts
  - EugeneHlushko
  - chenxsan
  - jamesgeorge007
  - snitin315
---

The `Compilation` module is used by the `Compiler` to create new compilations
(or builds). A `compilation` instance has access to all modules and their
dependencies (most of which are circular references). It is the literal
compilation of all the modules in the dependency graph of an application.
During the compilation phase, modules are loaded, sealed, optimized, chunked,
hashed and restored.

The `Compilation` class also extends `Tapable` and provides the following
lifecycle hooks. They can be tapped the same way as compiler hooks:

```js
compilation.hooks.someHook.tap(/* ... */);
```

As with the `compiler`, `tapAsync` and `tapPromise` may also be available
depending on the type of hook.

W> Since webpack 5, `hooks` are no longer extendable. Use a `WeakMap` to add custom hooks.

### buildModule

`SyncHook`

Triggered before a module build has started, can be used to modify the module.

- Callback Parameters: `module`

```js
compilation.hooks.buildModule.tap(
  'SourceMapDevToolModuleOptionsPlugin',
  (module) => {
    module.useSourceMap = true;
  }
);
```

### rebuildModule

`SyncHook`

Fired before rebuilding a module.

- Callback Parameters: `module`

### failedModule

`SyncHook`

Run when a module build has failed.

- Callback Parameters: `module` `error`

### succeedModule

`SyncHook`

Executed when a module has been built successfully.

- Callback Parameters: `module`

### finishModules

`AsyncSeriesHook`

Called when all modules have been built without errors.

- Callback Parameters: `modules`

### finishRebuildingModule

`SyncHook`

Executed when a module has been rebuilt, in case of both success or with errors.

- Callback Parameters: `module`

### seal

`SyncHook`

Fired when the compilation stops accepting new modules.

### unseal

`SyncHook`

Fired when a compilation begins accepting new modules.

### optimizeDependencies

`SyncBailHook`

Fired at the beginning of dependency optimization.

- Callback Parameters: `modules`

### afterOptimizeDependencies

`SyncHook`

Fired after the dependency optimization.

- Callback Parameters: `modules`

### afterChunks

`SyncHook`

<Badge text="5.83.0+" />

The `afterChunks` hook is invoked following the creation of the chunks and module graph, and prior to their optimization.
This hook provides an opportunity to examine, analyze, and modify the chunk graph if necessary.

Here's [an example](https://github.com/webpack/webpack/blob/10be3f9e3fb34078af8c5841a77025a6722f11bf/lib/wasm-sync/WebAssemblyModulesPlugin.js#L114-L137) of how to utilize the `compilation.hooks.afterChunks` hook.

- Callback Parameters: `chunks`

### optimize

`SyncHook`

Triggered at the beginning of the optimization phase.

### optimizeModules

`SyncBailHook`

Called at the beginning of the module optimization phase. A plugin can tap into this hook to perform optimizations on modules.

- Callback Parameters: `modules`

### afterOptimizeModules

`SyncHook`

Called after modules optimization has completed.

- Callback Parameters: `modules`

### optimizeChunks

`SyncBailHook`

Called at the beginning of the chunk optimization phase. A plugin can tap into this hook to perform optimizations on chunks.

- Callback Parameters: `chunks`

### afterOptimizeChunks

`SyncHook`

Fired after chunk optimization has completed.

- Callback Parameters: `chunks`

### optimizeTree

`AsyncSeriesHook`

Called before optimizing the dependency tree. A plugin can tap into this hook to perform a dependency tree optimization.

- Callback Parameters: `chunks` `modules`

### afterOptimizeTree

`SyncHook`

Called after the dependency tree optimization has completed with success.

- Callback Parameters: `chunks` `modules`

### optimizeChunkModules

`SyncBailHook`

Called after the tree optimization, at the beginning of the chunk modules optimization. A plugin can tap into this hook to perform optimizations of chunk modules.

- Callback Parameters: `chunks` `modules`

### afterOptimizeChunkModules

`SyncHook`

Called after the chunkmodules optimization has completed successfully.

- Callback Parameters: `chunks` `modules`

### shouldRecord

`SyncBailHook`

Called to determine whether or not to store records. Returning anything `!== false` will prevent every other "record" hook from being executed ([`record`](#record), [`recordModules`](#recordmodules), [`recordChunks`](#recordchunks) and [`recordHash`](#recordhash)).

### reviveModules

`SyncHook`

Restore module information from records.

- Callback Parameters: `modules` `records`

### beforeModuleIds

`SyncHook`

Executed before assigning an `id` to each module.

- Callback Parameters: `modules`

### moduleIds

`SyncHook`

Called to assign an `id` to each module.

- Callback Parameters: `modules`

### optimizeModuleIds

`SyncHook`

Called at the beginning of the modules `id` optimization.

- Callback Parameters: `modules`

### afterOptimizeModuleIds

`SyncHook`

Called when the modules `id` optimization phase has completed.

- Callback Parameters: `modules`

### reviveChunks

`SyncHook`

Restore chunk information from records.

- Callback Parameters: `chunks` `records`

### beforeChunkIds

`SyncHook`

Executed before assigning an `id` to each chunk.

- Callback Parameters: `chunks`

### chunkIds

`SyncHook`

Called to assign an `id` to each chunk.

- Callback Parameters: `chunks`

### optimizeChunkIds

`SyncHook`

Called at the beginning of the chunks `id` optimization phase.

- Callback Parameters: `chunks`

### afterOptimizeChunkIds

`SyncHook`

Triggered after chunk `id` optimization has finished.

- Callback Parameters: `chunks`

### recordModules

`SyncHook`

Store module info to the records. This is triggered if [`shouldRecord`](#shouldrecord) returns a truthy value.

- Callback Parameters: `modules` `records`

### recordChunks

`SyncHook`

Store chunk info to the records. This is only triggered if [`shouldRecord`](#shouldrecord) returns a truthy value.

- Callback Parameters: `chunks` `records`

### beforeModuleHash

`SyncHook`

Called before modules are hashed.

### afterModuleHash

`syncHook`

Called after modules are hashed.

### beforeHash

`SyncHook`

Called before the compilation is hashed.

### afterHash

`SyncHook`

Called after the compilation is hashed.

### recordHash

`SyncHook`

Store information about record hash to the `records`. This is only triggered if [`shouldRecord`](#shouldrecord) returns a truthy value.

- Callback Parameters: `records`

### record

`SyncHook`

Store information about the `compilation` to the `records`. This is only triggered if [`shouldRecord`](#shouldrecord) returns a truthy value.

- Callback Parameters: `compilation` `records`

### beforeModuleAssets

`SyncHook`

Executed before module assets creation.

### additionalChunkAssets

`SyncHook`

W> `additionalChunkAssets` is deprecated (use the [Compilation.hook.processAssets](#processassets) instead and use one of the Compilation.PROCESS_ASSETS_STAGE\_\* as a stage option)

Create additional assets for the chunks.

- Callback Parameters: `chunks`

### shouldGenerateChunkAssets

`SyncBailHook`

Called to determine whether or not generate chunks assets. Returning anything `!== false` will allow chunk assets generation.

### beforeChunkAssets

`SyncHook`

Executed before creating the chunks assets.

### additionalAssets

`AsyncSeriesHook`

W> `additionalAssets` is deprecated (use the [Compilation.hook.processAssets](#processassets) hook instead and use one of the Compilation.PROCESS_ASSETS_STAGE\_\* as a stage option)

Create additional assets for the compilation. This hook can be used to download
an image, for example:

```js
compilation.hooks.additionalAssets.tapAsync('MyPlugin', (callback) => {
  download('https://img.shields.io/npm/v/webpack.svg', function (resp) {
    if (resp.status === 200) {
      compilation.assets['webpack-version.svg'] = toAsset(resp);
      callback();
    } else {
      callback(
        new Error('[webpack-example-plugin] Unable to download the image')
      );
    }
  });
});
```

### optimizeChunkAssets

`AsyncSeriesHook`

W> `optimizeChunkAssets` is deprecated (use the [Compilation.hook.processAssets](#processassets) instead and use one of the Compilation.PROCESS_ASSETS_STAGE\_\* as a stage option)

Optimize any chunk assets. The assets are stored in `compilation.assets`. A
`Chunk` has a property `files` which points to all files created by a chunk.
Any additional chunk assets are stored in `compilation.additionalChunkAssets`.

- Callback Parameters: `chunks`

Here's an example that adds a banner to each chunk.

```js
compilation.hooks.optimizeChunkAssets.tapAsync(
  'MyPlugin',
  (chunks, callback) => {
    chunks.forEach((chunk) => {
      chunk.files.forEach((file) => {
        compilation.assets[file] = new ConcatSource(
          '/**Sweet Banner**/',
          '\n',
          compilation.assets[file]
        );
      });
    });

    callback();
  }
);
```

### afterOptimizeChunkAssets

`SyncHook`

W> `afterOptimizeChunkAssets` is deprecated (use the [Compilation.hook.processAssets](#processassets) instead and use one of the Compilation.PROCESS_ASSETS_STAGE\_\* as a stage option)

The chunk assets have been optimized.

- Callback Parameters: `chunks`

Here's an example plugin from [@boopathi](https://github.com/boopathi) that outputs exactly what went into each chunk.

```js
compilation.hooks.afterOptimizeChunkAssets.tap('MyPlugin', (chunks) => {
  chunks.forEach((chunk) => {
    console.log({
      id: chunk.id,
      name: chunk.name,
      includes: chunk.getModules().map((module) => module.request),
    });
  });
});
```

### optimizeAssets

`AsyncSeriesHook`

W> `optimizeAssets` is deprecated (use the [Compilation.hook.processAssets](#processassets) hook instead)

Optimize all assets stored in `compilation.assets`.

- Callback Parameters: `assets`

### afterOptimizeAssets

`SyncHook`

W> `afterOptimizeAssets` is deprecated (use the [Compilation.hook.afterProcessAssets](#afterprocessassets) hook instead)

The assets have been optimized.

- Callback Parameters: `assets`

### processAssets

`AsyncSeriesHook`

Asset processing.

**Hook parameters:**

- `name: string` — a name of the plugin
- `stage: Stage` — a stage to tap into (see the [list of supported stages](#list-of-asset-processing-stages) below)
- `additionalAssets?: true | (assets, [callback]) => (void | Promise<void>)` — a callback for additional assets ([see below](#additional-assets))

**Callback parameters:**

- `assets: { [pathname: string]: Source }` — a plain object, where key is the asset's pathname, and the value is data of the asset represented by the [`Source`](https://github.com/webpack/webpack-sources#source).

**Example:**

```js
compilation.hooks.processAssets.tap(
  {
    name: 'MyPlugin',
    stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS, // see below for more stages
  },
  (assets) => {
    console.log('List of assets and their sizes:');
    Object.entries(assets).forEach(([pathname, source]) => {
      console.log(`— ${pathname}: ${source.size()} bytes`);
    });
  }
);
```

#### Additional assets

In addition to `name` and `stage`, you can pass an `additionalAssets` <Badge text='5.8.0+' /> option which accepts either a value of `true` or a callback function that receives `assets` as a first argument:

1. `true` — run the provided callback again for assets added later by plugins.

   In this mode, the callback will be called multiple times: once for assets added prior to the specified stage, and additional times for assets added by plugins later (on this or next stages).

   ```js
   compilation.hooks.processAssets.tap(
     {
       name: 'MyPlugin',
       stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
       additionalAssets: true,
     },
     (assets) => {
       // this function will be called multiple times with each bulk of assets
     }
   );
   ```

2. `(assets, [callback]) => (void | Promise<void>)` — run the specified callback against assets added by plugins later (on this or next stages). The callback must respect the type of the tap method used (e.g. when used with `tapPromise()`, it should return a promise).

   ```js
   compilation.hooks.processAssets.tap(
     {
       name: 'MyPlugin',
       stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
       additionalAssets: (assets) => {
         // this function potentially could be called multiple times for assets added on later stages
       },
     },
     (assets) => {
       // this function will be called once with assets added by plugins on prior stages
     }
   );
   ```

#### List of asset processing stages

Here's a list of supported stages (in the order of processing):

- `PROCESS_ASSETS_STAGE_ADDITIONAL` — add additional assets to the compilation.
- `PROCESS_ASSETS_STAGE_PRE_PROCESS` — basic preprocessing of the assets.
- `PROCESS_ASSETS_STAGE_DERIVED` — derive new assets from the existing assets.
- `PROCESS_ASSETS_STAGE_ADDITIONS` — add additional sections to the existing assets e.g. banner or initialization code.
- `PROCESS_ASSETS_STAGE_OPTIMIZE` — optimize existing assets in a general way.
- `PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT` — optimize the count of existing assets, e.g. by merging them.
- `PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY` — optimize the compatibility of existing assets, e.g. add polyfills or vendor prefixes.
- `PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE` — optimize the size of existing assets, e.g. by minimizing or omitting whitespace.
- `PROCESS_ASSETS_STAGE_DEV_TOOLING` — add development tooling to the assets, e.g. by extracting a source map.
- `PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE` <Badge text='5.8.0+' /> — optimize the numbers of existing assets, e.g. by inlining assets into other assets.
- `PROCESS_ASSETS_STAGE_SUMMARIZE` — summarize the list of existing assets.
- `PROCESS_ASSETS_STAGE_OPTIMIZE_HASH` — optimize the hashes of the assets, e.g. by generating real hashes of the asset content.
- `PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER` — optimize the transfer of existing assets, e.g. by preparing a compressed (gzip) file as separate asset.
- `PROCESS_ASSETS_STAGE_ANALYSE` — analyze the existing assets.
- `PROCESS_ASSETS_STAGE_REPORT` — creating assets for the reporting purposes.

#### Assets info

The "asset info" metadata is not automatically provided for this hook. If needed, you will have to resolve this metadata manually using the compilation instance and the provided asset pathname. This will be improved in a future version of the webpack.

**Example:**

```js
compilation.hooks.processAssets.tap(
  {
    /** … */
  },
  (assets) => {
    Object.entries(assets).forEach(([pathname, source]) => {
      const assetInfo = compilation.assetsInfo.get(pathname);
      // @todo: do something with "pathname", "source" and "assetInfo"
    });
  }
);
```

### afterProcessAssets

`SyncHook`

Called after the [`processAssets`](#processassets) hook had finished without error.

### needAdditionalSeal

`SyncBailHook`

Called to determine if the compilation needs to be unsealed to include other files.

### afterSeal

`AsyncSeriesHook`

Executed right after `needAdditionalSeal`.

### chunkHash

`SyncHook`

Triggered to emit the hash for each chunk.

- Callback Parameters: `chunk` `chunkHash`

### moduleAsset

`SyncHook`

Called when an asset from a module was added to the compilation.

- Callback Parameters: `module` `filename`

### chunkAsset

`SyncHook`

Triggered when an asset from a chunk was added to the compilation.

- Callback Parameters: `chunk` `filename`

### assetPath

`SyncWaterfallHook`

Called to determine the path of an asset.

- Callback Parameters: `path` `options`

### needAdditionalPass

`SyncBailHook`

Called to determine if an asset needs to be processed further after being emitted.

### childCompiler

`SyncHook`

Executed after setting up a child compiler.

- Callback Parameters: `childCompiler` `compilerName` `compilerIndex`

### normalModuleLoader

Since webpack v5 `normalModuleLoader` hook was removed. Now to access the loader use `NormalModule.getCompilationHooks(compilation).loader` instead.

### statsPreset

`HookMap`

This HookMap is like a list of actions that gets triggered when a preset is used. It takes in an options object. When a plugin manages a preset, it should change settings in this object carefully without replacing existing ones.

- Callback Parameters: `options` `context`

Here's an illustrative plugin example:

```js
compilation.hooks.statsPreset.for('my-preset').tap('MyPlugin', (options) => {
  if (options.all === undefined) options.all = true;
});
```

This plugin ensures that for the preset `'my-preset'`, if the `all` option is undefined, it defaults to true.

### statsNormalize

`SyncHook`

This hook is used to transform an options object into a consistent format that can be easily used by subsequent hooks. It also ensures that missing options are set to their default values.

- Callback Parameters: `options` `context`

Here's an illustrative plugin example:

```js
compilation.hooks.statsNormalize.tap('MyPlugin', (options) => {
  if (options.myOption === undefined) options.myOption = [];

  if (!Array.isArray(options.myOption)) options.myOptions = [options.myOptions];
});
```

In this plugin, if the `myOption` is missing, it sets it to an empty array. Additionally, it ensures that `myOption` is always an array even if it was originally defined as a single value.

### statsFactory

This hook provides access to the [`StatsFactory` class](https://github.com/webpack/webpack/blob/main/lib/stats/StatsFactory.js) for specific options.

- Callback Parameters: `statsFactory` `options`

#### StatsFactory.hooks.extract

`HookMap`

- Callback Parameters: `object` `data` `context`

`data` contains the class. object is an object to which properties should be added. `context` provides contextual information, such as classes on the path.

Example:

```js
compilation.hooks.statsFactory.tap('MyPlugin', (statsFactory, options) => {
  statsFactory.hooks.extract
    .for('compilation')
    .tap('MyPlugin', (object, compilation) => {
      object.customProperty = MyPlugin.getCustomValue(compilation);
    });
});
```

#### StatsFactory.hooks.result

`HookMap`

Called with the result on each level.

- Callback Parameters: `result` `context`

### statsPrinter

This hook provides access to the [`StatsPrinter` class](https://github.com/webpack/webpack/blob/main/lib/stats/StatsPrinter.js) for specific options.

- Callback Parameters: `statsPrinter` `options`

#### StatsPrinter.hooks.print

`HookMap`

This hook is called when a part should be printed.

- Callback Parameters: `object` `context`

#### StatsPrinter.hooks.result

`HookMap`

This hook is called for the resulting string for a part.

- Callback Parameters: `result` `context`
